#include "sensor.h"

int min(int a, int b) {
  if (a < b) return a;
  else return b;
}

int max(int a, int b) {
  if (a > b) return a;
  else return b;
}

bool ordered(int a, int b, int c) {
  if (a<=b && b<=c) return true;
  else return false;
}

void *handler (void *t_msg) {
  char *msg = (char *) t_msg;
  char data[BSIZE];
  struct TDATA *tdata;
  int id,src,dest,type,  i;
  sscanf(msg, "%d,%d,%d;", src,dest,type);
  // Handle a client request.
  if (PULL == type) {
    int n, i1,i2,t1,t2,r1,r2,s1,s2;
    int ta,tc,ra,rc,sa,sc,tb,rb,sb;
    sscanf(msg, "%d,%d,%d,%d:%d,%d,%d,%d", 
                 i1,t1,r2,s1,i2,t2,r2,s2);
    ta = min(t1,t2); tc = max(t1,t2); 
    ia = min(i1,i2); ic = max(i1,i2);
    ra = min(r1,r2); rc = max(r1,r2);
    sa = min(s1,s2); sc = max(s1,s2);
    if (tc > time(NULL)) { 
      //Q,push((char *)t_msg); 
      break; 
    }

    char *r; FILE *R;
    r = itoa(RBEG+dest);
    R = fopen(r, "r");
    while (!feof(R)) {
        n=0;
        fscanf(R, "%d,%d,%d,%d\n", ib,tb,rb,sb);
        // If within range, send data.
        if (ia != NOT_SPEC) { if (ordered(ia,ib,ic)) n++; } else n++;
        if (ta != NOT_SPEC) { if (ordered(ta,tb,tc)) n++; } else n++;
        if (ra != NOT_SPEC) { if (ordered(ra,rb,rc)) n++; } else n++;
        if (sa != NOT_SPEC) { if (ordered(sa,sb,sc)) n++; } else n++;
        if (4 == n) {
          // Sign with repository id.
          tdata->src  = dest;
          tdata->dest = src;
          tdata->type = PUSH;
          bzero(data, BSIZE);
          sprintf(data, "%d,%d,%d;%d,%d,%d,%d;\n",
                        dest,src,PUSH,ib,tb,rb,sb);
          strcpy(tdata->msg, data); 
          sender(tdata);
        } 
    }
    fclose(R);
  } 
  else if (DATA == type) {
    int i,t,r,s;
    char *r; FILE *R;
    sscanf(msg, "%d,%d,%d,%d;\n", i,t,r,s);
    r = itoa(i%NUM_REPOS); 
    // TODO: Lock this. ----------------------
    R = fopen(r, "a+");                     //
    fprintf(R, "%d,%d,%d,%d\n", i,t,r,s);   //
    fclose(R);                              //
    // ---------------------------------------
  }
  return;
}
